package com.adv.ems.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.adv.ems.constants.EmsConst;
import com.adv.ems.db.entity.SystemConfigDO;
import com.adv.ems.db.entity.SystemWarningDO;
import com.adv.ems.enums.CollectPointWarningTypeEnum;
import com.adv.ems.manager.SystemConfigManager;
import com.adv.ems.manager.SystemWarningManager;
import com.adv.ems.model.dto.WarningConfigDTO;
import com.adv.ems.model.param.WarningDealParam;
import com.adv.ems.model.param.WarningListParam;
import com.adv.ems.model.vo.WarningListVO;
import com.adv.ems.service.WarningService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Service
public class WarningServiceImpl implements WarningService {
    @Resource
    SystemConfigManager systemConfigManager;
    @Resource
    SystemWarningManager systemWarningManager;

    private Map<String, Map<String, Date>> cache = new ConcurrentHashMap<String, Map<String, Date>>();

    @Override
    public void pushCollectPointWarning(Long refDataId, Long objId, Class objClass, CollectPointWarningTypeEnum type, String value, String msg) {
        boolean repeat = isRepeat(objId, objClass.getSimpleName(), type.name());
        if (repeat) {
            return;
        }
        SystemWarningDO warning = new SystemWarningDO();
        warning.setObjClsName(objClass.getSimpleName());
        warning.setObjId(objId);
        warning.setType(type.name());
        warning.setValue(value);
        warning.setMsg(msg);
        warning.setCreateTime(new Date());
        warning.setUpdateTime(new Date());
        systemWarningManager.insertData(warning);
    }

    @Override
    public List<SystemWarningDO> getTodayUnReadLastWarning(List<Long> pointIds, Class cls, List<String> types, Integer limit) {
        if (CollectionUtil.isEmpty(pointIds)) {
            return Collections.emptyList();
        }
        return systemWarningManager.getTodayUnReadLastWarning(pointIds, cls, types, limit);
    }

    @Override
    public WarningListVO list(WarningListParam param, String acceptLanguage) {
        WarningListVO result = new WarningListVO();
        List<SystemWarningDO> warnings = systemWarningManager.getList(param.getType(), param.getState(), param.getFromDate(), param.getToDate(), param.getPageNo(), param.getPageSize());
        if (warnings.size() > param.getPageSize()) {
            result.setHasMore(true);
            warnings = warnings.subList(0, param.getPageSize());
        }else {
            result.setHasMore(false);
        }
        List<WarningListVO.Info> collect = warnings.stream().map(WarningListVO.Info::new).collect(Collectors.toList());
        result.setList(collect);
        return result;
    }

    @Override
    public Boolean deal(WarningDealParam param, String acceptLanguage) {
        if (CollectionUtil.isEmpty(param.getIds())) {
            return true;
        }
        systemWarningManager.doneAll(param.getIds());
        return true;
    }

    private boolean isRepeat(Long objId, String objClsName, String type) {
        String key = String.format("%s_%s", objId, objClsName);
        Map<String, Date> dateMap = cache.getOrDefault(key, new ConcurrentHashMap<>());
        Date lastDate = dateMap.get(type);
        if (lastDate != null) {
            long dis = System.currentTimeMillis() - lastDate.getTime();
            boolean lessOne = (dis <= Duration.ofMinutes(1).toMillis());
            if (lessOne) {
                return true;
            }
            WarningConfigDTO config = getWarningConfigDTO();
            boolean lessConfig = (dis <= Duration.ofMinutes(config.getNoRepeatMinute()).toMillis());
            if (lessConfig) {
                return true;
            }
        }
        dateMap.put(type, new Date());
        cache.put(key, dateMap);
        return false;
    }

    private WarningConfigDTO getWarningConfigDTO() {
        List<SystemConfigDO> configs = systemConfigManager.selectByType(EmsConst.SystemConfigKey.WARNING_CONFIG);
        if (CollectionUtil.isEmpty(configs)) {
            return new WarningConfigDTO();
        }
        return JSONUtil.toBean(JSONUtil.toJsonStr(configs.get(0).getValue()), WarningConfigDTO.class);
    }
}
